import * as THREE from "three";
import gsap from "gsap";
interface CityMesh {
  material: THREE.MeshBasicMaterial;
  geometry: THREE.BufferGeometry;
}

export function modifyCityMaterial(mesh: CityMesh) {
  const { material } = mesh;

  material.onBeforeCompile = (shader) => {
    shader.fragmentShader = shader.fragmentShader.replace(
      "#include <dithering_fragment>",

      `#include <dithering_fragment>
     
         //#end#
         `
    );
    const compileReplaceProps = {
      shader,
      mesh,
    };
    addGradColor(compileReplaceProps);
    addSpread({
      ...compileReplaceProps,
      spreadInfo: {
        initParams: true,
        id: "1",
      },
    });
    // addLightLine({
    //   ...compileReplaceProps,
    //   spreadInfo:{
    //     initParams:true,

    //   }
    // })
    // 从下到上扫描
    addTopLine({
      ...compileReplaceProps,
      spreadInfo: {
        initParams: true,
      },
    });
  };
}
/**
 * 圆圈扩散效果
 * @param param0
 */
export function addSpread({
  shader,
  mesh,
  spreadInfo,
}: CompileReplaceProps & {
  spreadInfo?: {
    centerX?: number;
    centerY?: number;
    radius?: number;
    duration?: number;
    initParams?: boolean;
    id: string;
  };
}) {
  const defaultSpreadInfo = {
    centerX: 0,
    centerY: 0,
    radius: 500,
    duration: 2,
    initParams: false,
    id: "1",
  };
  if (!spreadInfo) {
    spreadInfo = defaultSpreadInfo;
  }
  spreadInfo = {
    ...defaultSpreadInfo,
    ...spreadInfo,
  };
  // 中心点
  shader.uniforms.uSpreadCenter = {
    value: new THREE.Vector2(spreadInfo.centerX, spreadInfo.centerY),
  };
  // 时间
  shader.uniforms.uSpreadTime = {
    value: 0,
  };
  // 条带的宽度
  shader.uniforms.uSpreadWidth = {
    value: 200,
  };
  if (spreadInfo.initParams) {
    shader.fragmentShader = shader.fragmentShader.replace(
      "#include <common>",
      `
  #include <common>
  uniform vec2 uSpreadCenter;
  uniform float uSpreadTime;
  uniform float uSpreadWidth;
  `
    );
  }

  shader.fragmentShader = shader.fragmentShader.replace(
    "//#end#",
    `
// 算出和中心点的距离
float spreadRadius${defaultSpreadInfo.id} = distance( vPosition.xz , uSpreadCenter ) ;
// 扩散范围
float spreadIndex${defaultSpreadInfo.id} = -( spreadRadius${defaultSpreadInfo.id} - uSpreadTime) * ( spreadRadius${defaultSpreadInfo.id} - uSpreadTime) + uSpreadWidth;
if(spreadIndex${defaultSpreadInfo.id} > 0.0){
  // 0-1的混合
  gl_FragColor = mix( gl_FragColor , vec4(1.0,1.0,1.0,1.0), spreadIndex${defaultSpreadInfo.id} / uSpreadWidth);
}
  //#end#
  `
  );

  gsap.to(shader.uniforms.uSpreadTime, {
    value: spreadInfo.radius,
    duration: spreadInfo.duration,
    ease: "none",
    repeat: -1,
  });
}

export interface CompileReplaceProps {
  shader: THREE.Shader;
  mesh: CityMesh;
}
/**
 * 根据物体高度算出渐变色
 * @param
 */
export function addGradColor({ shader, mesh }: CompileReplaceProps) {
  const { geometry } = mesh;

  geometry.computeBoundingBox();
  const min = geometry.boundingBox?.min;
  const max = geometry.boundingBox?.max;
  const uHeight = max && min ? max.y - min.y : 0;
  shader.uniforms.uTopColor = {
    value: new THREE.Color("#aaaeff"),
  };
  shader.uniforms.uHeight = {
    value: uHeight,
  };

  shader.vertexShader = (shader.vertexShader || "").replace(
    "#include <common>",
    `
          #include <common>
          varying vec3 vPosition;

          
          `
  );
  // 位置下发
  shader.vertexShader = (shader.vertexShader || "").replace(
    "#include <begin_vertex>",
    `
          #include <begin_vertex>
          vPosition = position;

          
          `
  );
  // 位置声明
  shader.fragmentShader = shader.fragmentShader.replace(
    "#include <common>",

    `#include <common>
      uniform vec3 uTopColor;
      uniform float uHeight;
      varying vec3 vPosition;
      
         
         `
  );

  shader.fragmentShader = shader.fragmentShader.replace(
    "//#end#",

    `

    vec4 distGradColor =  gl_FragColor;

    // 设置混合的百分比
    float gradMix = (vPosition.y +  (uHeight / 2.0)) / uHeight;
       // 计算混合颜色
       vec3 gradMixColor =  mix(distGradColor.xyz , uTopColor , gradMix);
       gl_FragColor = vec4( gradMixColor , 1.0);
       //#end#
       `
  );
}
/**
 * 直线扫描
 * @param param0
 */
export function addLightLine({
  shader,
  mesh,
  spreadInfo,
}: CompileReplaceProps & {
  spreadInfo?: {
    radius?: number;
    duration?: number;
    initParams?: boolean;
  };
}) {
  const defaultSpreadInfo = {
    radius: 800,
    duration: 2,
    initParams: false,
  };
  if (!spreadInfo) {
    spreadInfo = defaultSpreadInfo;
  }
  spreadInfo = {
    ...defaultSpreadInfo,
    ...spreadInfo,
  };

  // 时间
  shader.uniforms.uLightLineTime = {
    value: -1000,
  };
  // 条带的宽度
  shader.uniforms.uLightLineWidth = {
    value: 240,
  };
  if (spreadInfo.initParams) {
    shader.fragmentShader = shader.fragmentShader.replace(
      "#include <common>",
      `
  #include <common>

  uniform float uLightLineTime;
  uniform float uLightLineWidth;
  `
    );
  }

  shader.fragmentShader = shader.fragmentShader.replace(
    "//#end#",
    `

// 扩散范围
float lightLineMix = -( vPosition.x+ vPosition.z- uLightLineTime) * ( vPosition.x+ vPosition.z - uLightLineTime) + uLightLineWidth;
if(lightLineMix> 0.0){
  // 0-1的混合
  gl_FragColor = mix( gl_FragColor , vec4(1.0,1.0,1.0,1.0), lightLineMix / uLightLineWidth);
}
  //#end#
  `
  );

  gsap.to(shader.uniforms.uLightLineTime, {
    value: spreadInfo.radius,
    duration: spreadInfo.duration,
    ease: "none",
    repeat: -1,
  });
}

/**
 * 从下向上扫描
 * @param param0
 */
export function addTopLine({
  shader,
  mesh,
  spreadInfo,
}: CompileReplaceProps & {
  spreadInfo?: {
    radius?: number;
    duration?: number;
    initParams?: boolean;
  };
}) {
  const defaultSpreadInfo = {
    radius: 100,
    duration: 3,
    initParams: false,
  };
  if (!spreadInfo) {
    spreadInfo = defaultSpreadInfo;
  }
  spreadInfo = {
    ...defaultSpreadInfo,
    ...spreadInfo,
  };

  // 时间
  shader.uniforms.uLightLineTime = {
    value: -50,
  };
  // 条带的宽度
  shader.uniforms.uLightLineWidth = {
    value: 40,
  };
  if (spreadInfo.initParams) {
    shader.fragmentShader = shader.fragmentShader.replace(
      "#include <common>",
      `
  #include <common>

  uniform float uLightLineTime;
  uniform float uLightLineWidth;
  `
    );
  }

  shader.fragmentShader = shader.fragmentShader.replace(
    "//#end#",
    `

// 扩散范围
float lightLineMix = -( vPosition.y- uLightLineTime) * ( vPosition.y - uLightLineTime) + uLightLineWidth;
if(lightLineMix> 0.0){
  // 0-1的混合
  gl_FragColor = mix( gl_FragColor , vec4(0.8,0.8,1.0,1.0), lightLineMix / uLightLineWidth);
}
  //#end#
  `
  );

  gsap.to(shader.uniforms.uLightLineTime, {
    value: spreadInfo.radius,
    duration: spreadInfo.duration,
    ease: "none",
    repeat: -1,
  });
 
}
